﻿#pragma once
// Inner Fire 游戏引擎库
// 渲染项目类
//
// Copyright (c) 2023 by 尔西大帝. All rights reserved.
//
// 就是相当于GameObject。用于每个项目
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2024-11-19

#include <dx_core/dx_core.h>
#include <dx_core/simple_mesh.h>
#include <dx_model/material.h>

namespace ifire {
struct SkinnedModelInstance;
// Lightweight structure stores parameters to draw a shape.  This will
// vary from app-to-app.
struct RenderItem {
  RenderItem() = default;
  RenderItem(const RenderItem& rhs) = delete;

  bool Visible = true;

  // 世界矩阵
  XMFLOAT4X4 World = IDENTITY_4X4;
  XMFLOAT4X4 TexTransform = IDENTITY_4X4;

  // 用于GPU渲染
  DirectX::XMFLOAT2 DisplacementMapTexelSize = {1.0f, 1.0f};
  float GridSpatialStep = 1.0f;

  // 脏标志表示对象数据已更改，我们需要更新常量缓冲区。因为我们为每个
  // FrameResource 都有一个对象常量缓冲区， 我们必须将更新应用到每个
  // FrameResource。因此，当我们修改对象数据时，我们应该设置 dirty_count =
  // FRAME_RESOURCE_COUNT， 以便每个帧资源都能获得更新。
  int NumFramesDirty = FRAME_RESOURCE_COUNT;

  // 指向对应于此渲染项的 Object Buffer 的 GPU 常量缓冲区的索引。
  UINT ObjCBIndex = -1;

  // 网格对象
  SimpleMesh* Geo = nullptr;

  // 材质
  Material* Mat = nullptr;

  // 拓扑类型
  D3D12_PRIMITIVE_TOPOLOGY PrimitiveType = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;

  // 碰撞体
  BoundingBox Bounds;
  std::vector<InstanceData> Instances;

  // 用于DrawIndexedInstanced的参数.
  UINT IndexCount = 0;

  int InstanceCount = 0;
  UINT StartIndexLocation = 0;
  int BaseVertexLocation = 0;

  // Only applicable to skinned render-items.
  UINT SkinnedCBIndex = -1;

  // nullptr if this render-item is not animated by skinned mesh.
  SkinnedModelInstance* SkinnedModelInst = nullptr;
};

} // namespace ifire